package com.yanfei.zero.infrastructure.threads;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.springframework.util.Assert;
/**
 * 我们使用join方法等待CompletableFuture.allOf(futures).thenAccept方法注册的回调函数执行完成。
 * 这样，我们就可以确保在主线程执行完之前，回调函数能够执行完。
 * allOfFuture.get()方法来等待异步回调函数执行完成的方法是可行的，但是它会阻塞当前线程，直到回调函数执行完成并返回结果。
 * 相比之下，join方法也可以等待异步回调函数执行完成，但是它不会抛出InterruptedException和ExecutionException异常，
 * 而是将它们包装在CompletionException异常中。此外，join方法是CompletableFuture类的一部分，而不是Future接口的一部分，因此它更适合用于等待CompletableFuture的完成。
 * 因此，如果您使用allOfFuture.get()方法来等待异步回调函数执行完成，您需要处理InterruptedException和ExecutionException异常，并且需要将它们包装在RuntimeException或其他适当的异常中。
 * 如果您使用join方法，您不需要处理这些异常，因为它们已经被包装在CompletionException异常中。
 * 综上所述，虽然allOfFuture.get()方法和join方法都可以等待异步回调函数执行完成，但是join方法更适合用于等待CompletableFuture的完成。
 */
public class CompletableFutureExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 创建一个数组来存储CompletableFuture实例
    	
    	
    	
    	
        CompletableFuture<Integer>[] futures = new CompletableFuture[5];

        // 使用for循环创建并启动多个CompletableFuture任务
        for (int i = 0; i < 5; i++) {
            int taskNumber = i + 1;
            CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
                // 模拟一个耗时的任务，返回任务编号
                try {
                	if(taskNumber==5) {
//                		Assert.isTrue(false, "test");
                		
                		
                		
                	}
                	System.out.println("Task " + taskNumber + " completed");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return taskNumber;
            });
            futures[i] = future;
        }
        // 注册异步回调函数以处理所有CompletableFuture的结果
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures);
        System.out.println("All tasks completed");
        allOfFuture.thenAccept(v -> {
            System.out.println("v"+v);
        });

        // 等待回调函数执行完成，我们就可以确保在主线程执行完之前，回调函数能够执行完。
        allOfFuture.join();
        System.out.println("完成任务");
        
    }
}
